// 证件号生成与校验工具

export type DocumentType = 'C' | 'E'

// 通行证 C 的允许两位前缀（第二位字母）
const C_TWO_LETTER_PREFIXES: string[] = ['CA', 'CC', 'CD', 'CE', 'CF', 'CG', 'CH', 'CJ']

// 护照 E 的允许两位前缀（第二位字母）
const E_TWO_LETTER_PREFIXES: string[] = ['EA', 'EB', 'EC', 'ED', 'EE', 'EF', 'EG', 'EH', 'EJ', 'EK', 'EL', 'EM', 'EN', 'EP']

/** 获取随机整数 [0, max) */
function randomInt(max: number): number { return Math.floor(Math.random() * max) }

/**
 * 随机生成证件号码
 * 规则：前缀(1-2位) + 数字(7-8位) = 总长9；首位区分类型：C 通行证，E 护照。
 * - C 两位前缀可选：CA, CC, CD, CE, CF, CG, CH, CJ
 * - E 两位前缀可选：EA, EB, EC, ED, EE, EF, EG, EH, EJ, EK, EL, EM, EN, EP
 */
export function generateDocumentNumber(
  options?: {
    type?: DocumentType | 'random'
    twoLetterPrefix?: boolean | 'random'
  },
): string {
  const targetType: DocumentType = (options?.type === 'C' || options?.type === 'E')
    ? options!.type
    : (Math.random() < 0.5 ? 'E' : 'C')

  const useTwoLetter: boolean = options?.twoLetterPrefix === 'random'
    ? Math.random() < 0.5
    : (typeof options?.twoLetterPrefix === 'boolean' ? options!.twoLetterPrefix! : (Math.random() < 0.5))

  let prefix = targetType
  if (useTwoLetter) {
    if (targetType === 'C') {
      prefix = C_TWO_LETTER_PREFIXES[randomInt(C_TWO_LETTER_PREFIXES.length)]
    }
    else {
      prefix = E_TWO_LETTER_PREFIXES[randomInt(E_TWO_LETTER_PREFIXES.length)]
    }
  }

  const digitLength = prefix.length === 1 ? 8 : 7
  const numbers = Math.floor(Math.random() * 10 ** digitLength).toString().padStart(digitLength, '0')
  return `${prefix}${numbers}`
}

/** 校验是否为允许的两位前缀 */
function isAllowedTwoLetterPrefix(prefix: string): boolean {
  if (prefix.length !== 2)
    return false
  const first = prefix[0]
  if (first === 'C')
    return C_TWO_LETTER_PREFIXES.includes(prefix)
  if (first === 'E')
    return E_TWO_LETTER_PREFIXES.includes(prefix)
  return false
}

/**
 * 验证证件号码是否符合规则
 * - 总长9位
 * - 首位 C/E
 * - 若为单字母前缀：后随8位数字
 * - 若为两字母前缀：前缀必须在允许列表中，后随7位数字
 */
export function validateDocumentNumber(value: string | undefined | null): boolean {
  if (!value)
    return false
  const v = String(value).toUpperCase()
  if (v.length !== 9)
    return false
  const first = v[0]
  if (first !== 'C' && first !== 'E')
    return false

  const second = v[1]
  // 如果第二位是数字 => 视为单字母前缀
  if (second >= '0' && second <= '9') {
    const rest = v.slice(1)
    return /^\d{8}$/.test(rest)
  }

  // 两字母前缀
  const prefix = v.slice(0, 2)
  if (!isAllowedTwoLetterPrefix(prefix))
    return false
  const rest = v.slice(2)
  return /^\d{7}$/.test(rest)
}

/** 获取证件类型（首位字母） */
export function getDocumentType(value: string): DocumentType | null {
  if (!value)
    return null
  const c = value[0]?.toUpperCase()
  return c === 'C' || c === 'E' ? c : null
}

export const AllowedPrefixes = {
  C: C_TWO_LETTER_PREFIXES.slice(),
  E: E_TWO_LETTER_PREFIXES.slice(),
}
